/**
	License:		Artistic license 2.0 (see license.txt, also available online at http://www.perlfoundation.org/artistic_license_2_0)
	Authors:		OrbitalLab (http://www.orbitallab.ru/moonglide/), 2007-2009

	File:			ResShader.d
	Description:	shader compositor
	Date:			10.04.2009 by Digited
*/
module	moonglide.resources.resobjects.hilevel.ResShaderComposite;

public import moonglide.resources.resobjects.lowlevel.ResShader;

import moonglide.resources.Management;

//=============================================================
/// CResShaderComposite - shader compositor
//=============================================================
class CResShaderComposite : IResource
{
	protected:
		bool	_enabled = false;
		bool	_dead;
		ubyte	_loadedS=0;
		char[]	_id;

		this( char[] id )
		{
			handle = 0;
			CResManager().GenerateUniqueName( id );
			super( id );
			_New( this );
		}

	public:
		uint handle;

		void setNotLoaded() { _loadedS = 0; }
		void setLoading() { _loadedS = 1; }
		void setLoaded() { _loadedS = 2; }
		bool loaded() { return _loadedS == 2; }

		CResShader[3] progs;
		ubyte shaderType; // Shader_GLSL  or	Shader_ARB. for OpenGL

		void	id( char[] newid ) { if( !loaded ) _id = newid; }
		char[]	id() { return _id; }

		bool enabled() { return _enabled; }
		bool isAlive() { return !_dead; }

		// sType = { sh_Vertex = 0,	sh_Fragment = 1,	sh_Geometry = 2 }
		void setProg( ubyte sType , CResShader prog )
		{
			prog.sType = sType;
			progs[ sType ] = prog;
			_enabled = true;
		}


		SShaderLoc* getLocalByName( char[] Xname, ubyte shadType = 0 )
		{
			if( progs[ shadType ] )
				with( progs[ shadType ] )
					for( int i=0; i<locals.length; ++i )
						if( locals[i].name == Xname )
							return &locals[i];

			return null;
		}

		SShaderLoc* getLocalByNum( int Xnum, ubyte shadType )
		{
			if( progs[ shadType ] )
				with( progs[ shadType ] )
					for( int i=0; i<locals.length; ++i )
						if( locals[i].num == Xnum )
							return &locals[i];

			return null;
		}

		// shadType is used only with ARB
		void addLocal ( T )( char[] Xname, T _fdata, bool xIsStatic, ubyte shadType = sh_Vertex )
		{
			with( progs[ shadType ] )
			{
				locals.length = locals.length + 1;

				with( locals[$-1] )
				{
					name = Xname;
					isStatic = xIsStatic;
					setData( _fdata );
				}
			}
		}

		static CResShaderComposite opCall( char[] id )
		{
			return new CResShaderComposite( id );
		}

		~this()
		{
			foreach( ref prog; progs )
				if( prog )
				{
					if( prog.isAlive )
						prog.release;

					prog = null;
				}
		}
}